package com.aivin.lib_reader.tool;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.text.TextUtils;


import com.aivin.lib_reader.ReaderConfig;
import com.aivin.lib_reader.bean.ShowLine;

import java.text.DecimalFormat;
import java.util.List;

/**
 * 阅读界面绘制的具体实现类
 */
@SuppressWarnings("WeakerAccess")
public class ReaderResolve {
    /*** 表示最后一个*/
    public static final int LAST_INDEX = -1;
    /**表示第一个*/
    public static final int FIRST_INDEX = 0;
    /**本章在总章节中的索引*/
    private int mChapterIndex;

    /**当前章节的文字内容(正文)*/
    private String mContent = "";
    /**当前章节标题*/
    private String mTitle = "";
    /**总章节数*/
    private int mChapterSum;
    /**阅读器控件总的长宽*/
    private int mAreaWidth ,mAreaHeight;


    /**当前章节总页数 , -1 代表当前页的内容为空 */
    private int mPageSum;
    /**本章中 ，当前页码*/
    private int mPageIndexAtChapter;
    /**当前页第一个字符在本章中的索引*/
    private int mCharIndexAtChapter;

    /**
     * 正文 内容
     */
    private List<ShowLine> mShowLines;
    /**
     * 标题内容
     */
    private List<ShowLine> mChapterNameLines;

    /**
     * 一页能展示多少行（除第0页） , 因为第0页 有一个大标题要显示
     */
    private int mLineNumPerPageWithoutFirstPage;
    /**
     * 一页能展示多少行（第0页）
     */
    private int mLineNumPerPageInFirstPage;

    /**
     * 第0页大章节名称所占高度
     */
    private int mChapterTitleHeight;
    /**
     *  画章节名称的Paint
     */
    private Paint mChapterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    /**
     * 正文的画笔
     */
    private Paint mMainBodyPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    /**
     * 画边缘的画笔，如：页码、章节名称、电池等
     */
    private Paint mMarginPaint = new Paint(Paint.ANTI_ALIAS_FLAG);


    private DecimalFormat decimalFormat = new DecimalFormat("#0.00");

    /**
     * 界面布局配置
     */
    private ReaderConfig mReaderConfig;


    public ReaderResolve( ReaderConfig readerConfig) {
        this.mReaderConfig = readerConfig;
        initPaints();
    }

    private void initPaints() {
        mMainBodyPaint.setColor( Color.BLACK);
        mMainBodyPaint.setTextSize(mReaderConfig.getTextSize());

        mChapterPaint.setTextSize(mReaderConfig.getTextSize() * 1.4f);
        mChapterPaint.setColor(Color.RED);

        mMarginPaint.setColor(Color.BLUE );
        mMarginPaint.setTextSize(mReaderConfig.getTextSize() *0.8f);
    }


    /**
     * 计算当前章节的相关参数
     * eg: mPageSum，总行数等等。。
     */
    private void calculateChapterParameter() {
        // 阅读器的绘制区域
        int paddingLeft =   mReaderConfig.getPadding()[0];
        int paddingTop =    mReaderConfig.getPadding()[1];
        int paddingRight =  mReaderConfig.getPadding()[2];
        int paddingBottom = mReaderConfig.getPadding()[3];
        int usableWidth = mAreaWidth - paddingLeft - paddingRight;
        int usableHeight = mAreaHeight - paddingTop - paddingBottom;

        // 标题
        mChapterNameLines = TextBreakUtils.breakToLineList(mTitle, usableWidth, 0, mChapterPaint);
        Paint.FontMetrics chapterFM = mChapterPaint.getFontMetrics();
        mChapterTitleHeight = (int) (  mChapterNameLines.size()  * ( chapterFM.bottom - chapterFM.top + mReaderConfig.getLineSpace() ) );

        //正文
        if (!TextUtils.isEmpty(mContent)) {
            mShowLines = TextBreakUtils.breakToLineList(mContent, usableWidth, 0, mMainBodyPaint);
        }

        //总页数
        mLineNumPerPageInFirstPage =       TextBreakUtils.measureLines(usableHeight - mChapterTitleHeight, mReaderConfig.getLineSpace(), mMainBodyPaint);
        mLineNumPerPageWithoutFirstPage = TextBreakUtils.measureLines(usableHeight, mReaderConfig.getLineSpace(), mMainBodyPaint);
        if (mShowLines != null) {
            // todo : 这句还不懂
            mPageSum = mShowLines.size() <= mLineNumPerPageInFirstPage ?   1 : ( mShowLines.size() - mLineNumPerPageInFirstPage  - 1)  / Math.max( 1, mLineNumPerPageWithoutFirstPage)     + 1 + 1;
            calculatePageIndex();
        } else {
            mPageSum = -1;
        }
    }

    /**
     * 根据字符索引 ,计算页码
     */
    private void calculatePageIndex() {
        if (mCharIndexAtChapter == FIRST_INDEX) {
            mPageIndexAtChapter = 0;
        } else if (mCharIndexAtChapter == LAST_INDEX) {
            mPageIndexAtChapter = mPageSum - 1;
        } else if (mCharIndexAtChapter >= mContent.length()) {
            mPageIndexAtChapter = mPageSum - 1;
        } else {
            //step 1.计算当前字符索引在哪一行
            // 为了提升效率，如果字符索引在mContent.length()后半部分，则从后半部分遍历
            int lineIndex = 0;
            if ( mCharIndexAtChapter >= mContent.length() / 2) {
                for (int i = mShowLines.size() - 1; i >= 0; --i) {
                    ShowLine showLine = mShowLines.get(i);
                    if (mCharIndexAtChapter >= showLine.getLineFirstIndexInChapter() && mCharIndexAtChapter <= showLine.getLineLastIndexInChapter()) {
                        lineIndex = i;
                        break;
                    }
                }
            } else {
                for (int i = 0; i <= mShowLines.size() - 1; i++) {
                    ShowLine showLine = mShowLines.get(i);
                    if (mCharIndexAtChapter >= showLine.getLineFirstIndexInChapter() && mCharIndexAtChapter <= showLine.getLineLastIndexInChapter()) {
                        lineIndex = i;
                        break;
                    }
                }
            }
            //step 2.计算lineIndex在哪一页
            if (lineIndex <= mLineNumPerPageInFirstPage - 1) {
                mPageIndexAtChapter = 0;
            } else {
                mPageIndexAtChapter = (lineIndex - mLineNumPerPageInFirstPage) / mLineNumPerPageWithoutFirstPage + 1;
            }
        }
    }

    public void drawPage(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

        // 标题 ， 第0页需要画章节大标题
        if (mTitle != null && mPageIndexAtChapter==0) {
            maybeDrawChapterTitle(canvas);
        }

        // 正文
        if (mShowLines != null ) {
            drawMainBodyArea(canvas);
        }

        // 进度
        if (mPageSum != -1) {
            mMarginPaint.setColor(Color.RED);

            // 当前章进度
            String infoStr = (mPageIndexAtChapter + 1) + "/" + mPageSum   ;

            //整书进度。
            float percent =  mChapterIndex * 100f / mChapterSum  +    (mPageIndexAtChapter + 1) * 100f / mPageSum / mChapterSum;
            String percentStr = decimalFormat.format(percent) + "%";

            infoStr = infoStr+" | "+percentStr ;
            canvas.drawText(infoStr,  mAreaWidth - mReaderConfig.getPadding()[2]- mMarginPaint.measureText(infoStr),
                    mAreaHeight- mReaderConfig.getPadding()[1]/3f,   mMarginPaint);

            // 时间
            String timenow =StringTool.getCurrentDataStr();
            canvas.drawText(timenow,  mReaderConfig.getPadding()[2],
                    mAreaHeight- mReaderConfig.getPadding()[1]/3f,   mMarginPaint);
        }
    }



    /**
     * 如果是第0页需要画章节大标题
     */
    private void maybeDrawChapterTitle(Canvas canvas) {
        Paint.FontMetrics pfm = mChapterPaint.getFontMetrics();
        float y =  (int)( mReaderConfig.getPadding()[1] + (pfm.bottom - pfm.top)) +    mReaderConfig.getLineSpace() / 2f;
        for (int i = 0; i < mChapterNameLines.size(); i++) {
            canvas.drawText(mChapterNameLines.get(i).getLineData(), mReaderConfig.getPadding()[0], y, mChapterPaint);
            y += (pfm.bottom - pfm.top) + mReaderConfig.getLineSpace();
        }
    }

    /**
     * 画正文
     */
    private void drawMainBodyArea(Canvas canvas) {
        Paint.FontMetrics fm = mMainBodyPaint.getFontMetrics();
        float textHeight = fm.bottom - fm.top;

        float x = mReaderConfig.getPadding()[0];
        float y = mReaderConfig.getPadding()[1] + textHeight + mReaderConfig.getLineSpace() / 2f;

        if (mPageIndexAtChapter == 0) {
            y += mChapterTitleHeight; // 第一页有大标题占了位置
        }

        for (int i = 0; i < (mPageIndexAtChapter == 0 ? mLineNumPerPageInFirstPage : mLineNumPerPageWithoutFirstPage); i++) {
            //要画的这行在整章中的索引
            int lineInChapter=  mPageIndexAtChapter == 0 ?  i :  mLineNumPerPageWithoutFirstPage * (mPageIndexAtChapter - 1) + mLineNumPerPageInFirstPage + i;

            if (lineInChapter > mShowLines.size() - 1) {
                break;
            }
            ShowLine showLine = mShowLines.get(lineInChapter);
            canvas.drawText( showLine.getLineData(), x, y, mMainBodyPaint);
            y += (textHeight + mReaderConfig.getLineSpace());
        }
    }


    /**
     * @return 当前页第一个字符索引
     */
    public int getCurrPageFirstCharIndex() {
        if (mPageIndexAtChapter == 0) {
            return 0;
        } else {
            int pageFirstLineIndex = mLineNumPerPageInFirstPage + (mPageIndexAtChapter - 1) * mLineNumPerPageWithoutFirstPage;
            return mShowLines.get(pageFirstLineIndex).getLineFirstIndexInChapter();
        }
    }

    public int getPageIndex() {
        return mPageIndexAtChapter;
    }

    /**
     * 设置本章页码， 页码从 0开始的
     */
    public void setPageIndex(int pageIndex) {
        mPageIndexAtChapter = pageIndex;
    }

    public int getChapterIndex() {
        return mChapterIndex;
    }

    public void setChapterIndex(int chapterIndex) {
        mChapterIndex = chapterIndex;
    }

    public int getPageSum() {
        return mPageSum;
    }



    public int getChapterSum() {
        return mChapterSum;
    }

    public void setChapterSum(int chapterSum) {
        mChapterSum = chapterSum;
    }

    public int getCharIndex() {
        return mCharIndexAtChapter;
    }

    public void setCharIndex(int charIndex) {
        mCharIndexAtChapter = charIndex;
    }

    public void setArea(int areaWidth, int areaHeight) {
        this.mAreaWidth = areaWidth;
        this.mAreaHeight = areaHeight;
        calculateChapterParameter(); // setArea
    }


    public void setTitle( String title) {
        this.mTitle = title;
    }

    public void setContent( String content) {
        if (content == null) {
            mShowLines = null;
        }
        mContent = content;
        calculateChapterParameter(); // setContent
    }



    public void setReaderConfig(  ReaderConfig readerConfig) {
        ReaderConfig oldReaderConfig = mReaderConfig;
        mReaderConfig = readerConfig;

        int oldTextSize = oldReaderConfig.getTextSize();
        int oldLineSpace = oldReaderConfig.getLineSpace();
        int[] oldPadding = oldReaderConfig.getPadding();

        int newTextSize = readerConfig.getTextSize();
        int newLineSpace = readerConfig.getLineSpace();
        int[] newPadding = readerConfig.getPadding();


        if (oldTextSize != newTextSize     ) {
            initPaints();
        }

        if (oldTextSize != newTextSize || oldLineSpace != newLineSpace || oldPadding != newPadding) {
            calculateChapterParameter(); // setReaderConfig
        }
    }




}
